package com.net.xpay.common.service.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.net.xpay.common.domain.stat.TransStat;
import com.net.xpay.common.helper.RedisHelper;
import com.net.xpay.common.manager.sync.CommonPayTransBatchManager;
import com.net.xpay.common.model.TransStatModel;
import com.net.xpay.common.model.TransStatSumDataModel;
import com.net.xpay.core.constant.RedisKey;
import com.net.xpay.core.manager.PayTransManager;
import com.net.common.util.LocalDateUtil;
import com.net.common.util.SerializationUtil;
import com.net.xpay.common.service.TransStatService;
import com.net.shard.ShardDataSource;
import com.net.shard.ShardDataSourceConfigurer;
import com.net.shard.ShardUtil;
import com.net.shard.domain.ShardConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class TransStatServiceImpl implements TransStatService {

    @Autowired
    private CommonPayTransBatchManager commonPayTransBatchManager;

    @Autowired
    private RedisHelper redisHelper;

    @Autowired
    private PayTransManager payTransManager;

    @Autowired
    @Qualifier("shardDataSource")
    private DataSource shardDataSource;



    /**
     * 统计日账单
     *
     * @param day 日期
     * @return 日账单
     */
    @Override
    public TransStat sumTransStat(LocalDate day) {
        // 根据当前时间获取改天的起始时间和结束时间
        LocalDateTime startTime = LocalDateUtil.getDayStart(day);
        LocalDateTime endTime = LocalDateUtil.getDayStart(day.plusDays(1L));
        TransStat billDailyStat = TransStat.getInstance(day);

        //转账数据
        TransStatModel statModel = commonPayTransBatchManager.sumTransStat(startTime, endTime);
        billDailyStat.setTotalCount(statModel.getTotalCount());
        billDailyStat.setTotalTransAmount(statModel.getTotalTransAmount());
        billDailyStat.setFailCount(statModel.getFailCount());
        billDailyStat.setFailedAmount(statModel.getFailedAmount());
        billDailyStat.setSuccessAmount(new BigDecimal(statModel.getSuccessAmount()).setScale(2, RoundingMode.HALF_UP).toString());
        billDailyStat.setSuccessCount(statModel.getSuccessCount());

        //当日付款支付宝数量
        long paidAlipayUserCount = commonPayTransBatchManager.sumTotalPaidAlipayUserCount(startTime, endTime);
        billDailyStat.setPaidAlipayUserCount(paidAlipayUserCount);

        //当日收款支付宝数量
        billDailyStat.setReceiveAlipayCount(statModel.getSuccessCount());

        if (billDailyStat.getTotalCount() == 0L) {
            billDailyStat.setTransSuccessRate(new BigDecimal(0));
        } else {
            BigDecimal transSuccessRate = new BigDecimal(billDailyStat.getSuccessCount()).divide(new BigDecimal(billDailyStat.getTotalCount()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
            billDailyStat.setTransSuccessRate(transSuccessRate);
        }

        //当日单笔超过500金额的笔数 这个得切库查询
        ShardDataSourceConfigurer shardDataSourceConfigurer = ((ShardDataSource) shardDataSource).getShardDataSourceConfigurer();
        Map<Long, ShardConfig> shardConfigMap = shardDataSourceConfigurer.getShardConfigMap();
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(shardConfigMap.keySet()));

        long singleVeryCount = 0L;
        List<Long> singleVeryMerchantIds = new ArrayList<>();
        for (Long shardId : shardConfigMap.keySet()) {
            try {
                ShardUtil.setShardContext(shardId);
                long shardSingleVeryCount = payTransManager.statSingleVeryCount(startTime, endTime);

                singleVeryCount += shardSingleVeryCount;

                List<Long> shardSingleVeryMerchantIds = payTransManager.listSingleVeryMerchantIds(startTime, endTime);
                singleVeryMerchantIds.addAll(shardSingleVeryMerchantIds);
            } finally {
                ShardUtil.cleanShardContext();
            }
        }

        billDailyStat.setSingleVeryCount(singleVeryCount);
        billDailyStat.setSingleVeryMerchantIds(Joiner.on(",").join(singleVeryMerchantIds));

        return billDailyStat;
    }

    @Override
    public TransStatSumDataModel getSumData() {
        //从Redis获取数据
        Object dataObj = redisHelper.get(RedisKey.TRANS_STAT_SUM_DATA);
        if (dataObj != null) {
            return SerializationUtil.str2Object(dataObj.toString(), TransStatSumDataModel.class);
        }

        TransStatSumDataModel model = commonPayTransBatchManager.sumAccumulatedData();
        model.setStatTime(LocalDateTime.now());

        //累计超过500w支付宝所属商户
        List<Long> veryMerchantIds = commonPayTransBatchManager.listTotalVeryMerchantIds();
        model.setVeryMerchantIds(Joiner.on(",").join(veryMerchantIds));

        redisHelper.set(RedisKey.TRANS_STAT_SUM_DATA, SerializationUtil.obj2String(model), 3600 * 12L);

        return model;
    }


}